package com.mitou.common.generator;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.IFill;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.io.File;
import java.util.*;

/**
 * 代码生成器 对应mp版本3.5.1+
 *
 * @author rice
 * @since 2021-10-21
 */
public class CodeGenerator351 {

    public static void main(String[] args) {
        //mysql相关配置
        String mysqlUrl = "jdbc:mysql://localhost:3306/mitou";
        String mysqlUsername = "root";
        String mysqlPassword = "123456";
        //表名
        String tableNames = "base_user,base_role";
        String tablePrefix = "";
        //包、模块名
        String parentPackage = "com.mitou";
        String moduleName = "user2";
        //作者
        String author = "rice";
        //生成项目输出路径
        String projectPath = System.getProperty("user.dir") + "/src/main/java/";
        //表字段填充
        List<IFill> iFillList = Arrays.asList(
                new Column("create_time", FieldFill.INSERT),
                new Column("update_time", FieldFill.INSERT_UPDATE),

                new Column("create_user_id", FieldFill.INSERT),
                new Column("create_by", FieldFill.INSERT),
                new Column("create_user_name", FieldFill.INSERT),

                new Column("update_user_id", FieldFill.INSERT_UPDATE),
                new Column("update_by", FieldFill.INSERT_UPDATE),
                new Column("update_user_name", FieldFill.INSERT_UPDATE)
        );
        //逻辑删除字段
        String logicDeleteColumnName = "del_flag";


////*****************************************分割线*****************************************////
        FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(mysqlUrl + "?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8", mysqlUsername, mysqlPassword);
        fastAutoGenerator.globalConfig(builder -> {
            builder.author(author)
                    .enableSwagger()
                    .dateType(DateType.ONLY_DATE) // 指定java中使用的时间类型
                    .fileOverride() // 覆盖已生成文件
                    .disableOpenDir()
                    .outputDir(projectPath);
        });
        fastAutoGenerator.packageConfig(builder -> {
            builder.parent(parentPackage)
                    .moduleName(moduleName)
                    .mapper("dao")
                    .other("")
                    .pathInfo(
                            new HashMap<OutputFile, String>() {{
                                // 设置mapperXml生成路径
                                put(OutputFile.mapperXml, projectPath + parentPackage.replace(".", "/") + "/" + moduleName + "/mapper/xml/");
                                // 设置mapper生成路径
                                put(OutputFile.mapper, projectPath + parentPackage.replace(".", "/") + "/" + moduleName + "/mapper/");
                                // 设置serviceImpl生成路径
                                put(OutputFile.serviceImpl, projectPath + parentPackage.replace(".", "/") + "/" + moduleName + "/service/impl/");
                                // 设置service生成路径
                                put(OutputFile.service, projectPath + parentPackage.replace(".", "/") + "/" + moduleName + "/service/");
                                // 设置entity生成路径
                                put(OutputFile.entity, projectPath + parentPackage.replace(".", "/") + "/" + moduleName + "/entity/");
                            }}
                    );
        });
        fastAutoGenerator.strategyConfig(builder -> {
            builder.addInclude(tableNames.split(",")).addTablePrefix(tablePrefix)
                    .controllerBuilder().enableRestStyle()
                    .entityBuilder().enableLombok().enableTableFieldAnnotation().idType(IdType.ASSIGN_ID).addTableFills(iFillList).logicDeleteColumnName(logicDeleteColumnName)
                    .serviceBuilder().formatServiceFileName("I%sService")
                    .mapperBuilder().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper")
                    .build();
        });
        fastAutoGenerator.injectionConfig(builder -> {
            //重写了outputCustomFile，所以不用自带的了
//                    builder.customFile(customFile);
        });
        fastAutoGenerator.templateConfig(builder -> {
//                    builder.entity("templates/entity.java");
        });
        fastAutoGenerator.templateEngine(new FreemarkerTemplateEngine() {
            @Override
            protected void outputCustomFile(Map<String, String> customFile, TableInfo tableInfo, Map<String, Object> objectMap) {
                // 输出前的自定义
                String entityName = tableInfo.getEntityName();
                String otherPath = getPathInfo(OutputFile.other);
                String queryName = otherPath + "/entity"+ File.separator + "query" + File.separator + entityName + "Query.java";
                //todo 可以在此自定义一些属性，模板上进行使用
                objectMap.put("parentModel", parentPackage + "." + moduleName);
                objectMap.put("parentPackage", parentPackage);
                outputFile(new File(queryName), objectMap, "templates/query.java.ftl");
                //生成 Struct.java
                String structName = otherPath + File.separator + "mapstruct" + File.separator + entityName + "Struct.java";
                outputFile(new File(structName), objectMap, "templates/mapstruct.java.ftl");
                //生成 Dto.java
                String dtoName = otherPath + "/entity" + File.separator + "dto" + File.separator + entityName + "Dto.java";
                outputFile(new File(dtoName), objectMap, "templates/dto.java.ftl");
                //生成 Vo.java
                String voName = otherPath + "/entity" + File.separator + "vo" + File.separator + entityName + "Vo.java";
                outputFile(new File(voName), objectMap, "templates/vo.java.ftl");
            }

            @Override
            public AbstractTemplateEngine batchOutput() {
                try {
                    ConfigBuilder config = this.getConfigBuilder();
                    List<TableInfo> tableInfoList = config.getTableInfoList();
                    tableInfoList.forEach(tableInfo -> {
                        Map<String, Object> objectMap = this.getObjectMap(config, tableInfo);
                        Optional.ofNullable(config.getInjectionConfig()).ifPresent(t -> {
                            t.beforeOutputFile(tableInfo, objectMap);
                            // 输出自定义文件
                            outputCustomFile(t.getCustomFile(), tableInfo, objectMap);
                        });
                        //todo 可以在此自定义一些属性，模板上进行使用
                        objectMap.put("parentPackage", parentPackage);
                        objectMap.put("parentModel", parentPackage + "." + moduleName);

                        // Mp.java
                        tableInfo.setEntityName(tableInfo.getEntityName().concat("Entity"));
                        outputEntity(tableInfo, objectMap);
                        // mapper and xml
                        outputMapper(tableInfo, objectMap);
                        // service
                        outputService(tableInfo, objectMap);
                        // MpController.java
                        outputController(tableInfo, objectMap);
                    });
                } catch (Exception e) {
                    throw new RuntimeException("无法创建文件，请检查配置信息！", e);
                }
                return this;
            }
        });
        fastAutoGenerator.execute();// 自定义输出
    }

}